<template>
  <div class="three-car">
    <div class="car-header">
      <van-icon name="arrow-left" @click="goBack" class="img" />
    </div>
    <div class="car-content">
      <div id="canvas" ref="canvas"></div>
      <div class="car-scale" @click="onThreeSizeChange()">
        <van-icon name="exchange" size="30" />
      </div>
    </div>
    <div class="car-color">
      <ul>
        <li
          v-for="threeCarItem in threeCar"
          @click="onCarColorChange(threeCarItem)"
        >
          <p :style="{ background: threeCarItem.color }"></p>
        </li>
      </ul>
    </div>
    <div class="car-footer">
      <div class="car-picture">
        
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref } from "@vue/reactivity";
import { onBeforeMount, onMounted } from "@vue/runtime-core";
import * as Three from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { Toast } from "vant";
import { useRoute, useRouter } from "vue-router";

onMounted(() => {
  getThreeCanvas(window.innerWidth, canvas.value.clientHeight, tempImg);
  Toast.clear()
});

const canvas = ref(null);

let renderer = null;

let texture = null;

let tempImg = null;

const flag = ref(true);

const route = useRoute();

const router = useRouter();

const threeCar = ref(null);

const goBack = () => router.back(-1);

const onThreeSizeChange = async () => {
  flag.value = !flag.value
  await ToastChange(true);
  if (flag.value === false) {
    await getThreeCanvas(window.innerWidth, window.innerHeight - 40, tempImg);
  } else {
    await getThreeCanvas(window.innerWidth, canvas.value.clientHeight, tempImg);
  }
};

const onCarColorChange = async (e) => {
  if (tempImg === e.vr_list.front_vr) return;
  await ToastChange(e.vr_list.front_vr);
};

const ToastChange = async (arg) => {
  Toast.loading({
    message: "加载中...",
    forbidClick: true,
    duration: 0,
  });
  await canvas.value.removeChild(renderer.domElement);
  new Promise(async (resolve, reject) => {
    if (typeof arg === "boolean") {
      await resolve(arg);
    }
    if (typeof arg === "string") {
      await getThreeCanvas(window.innerWidth, canvas.value.clientHeight, arg);
    }
    await resolve(arg);
  }).then((arg) => {
    if (typeof arg === "string") tempImg = arg;
    Toast.clear();
  });
};

const getThreeCanvas = (width, height, url) => {
  let scene = new Three.Scene();
  texture = new Three.TextureLoader().load(url); // 加载背景图
  let sphereGeometry = new Three.SphereGeometry(200, 200, 200); //创建一个球体几何对象Geometry
  /** Radius（半径） widthSegments (经度上的分段数) heightSegments (纬度上的分段数)  段数越多，球体的表面越光滑*/
  let material = new Three.MeshLambertMaterial({
    // color: 0x0000ff,
    map: texture,
    toneMapped: false,
    transparent: true,
  }); //材质对象Material
  sphereGeometry.scale(-1, 1, 1);
  let mesh = new Three.Mesh(sphereGeometry, material); //网格模型对象Mesh
  mesh.position.set(0, 0, 0);
  mesh.receiveShadow = true;
  // 箱子去投射光源
  mesh.castShadow = true;
  scene.add(mesh); //网格模型添加到场景中
  /**
   * 光源设置
   */
  //点光源
  //   let point = new Three.PointLight(0xffffff);
  //   point.position.set(20, 30, 20); //点光源位置
  //   scene.add(point); //点光源添加到场景中
  //环境光
  let ambient = new Three.AmbientLight(0xffffff);
  scene.add(ambient);
  /**
   * 相机设置
   */
  //   let width = window.innerWidth; //窗口宽度
  //   let height = 300; //窗口高度
  let k = width / height; //窗口宽高比
  let s = 70; //三维场景显示范围控制系数，系数越大，显示的范围越大
  //创建相机对象
  let camera = new Three.PerspectiveCamera(s, k, 0.1, 1000); // left top near far
  camera.position.set(50, 0, 0); //设置相机位置
  camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
  /**
   * 创建渲染器对象
   */
  renderer = new Three.WebGLRenderer({
    antialias: true, //抗锯齿
  });

  renderer.setPixelRatio(window.devicePixelRatio); //设备像素比
  renderer.setSize(width, height); //设置渲染区域尺寸
  renderer.setClearColor(0xffffff, 1); //设置背景颜色
  renderer.setAnimationLoop(loopAnimation);
  canvas.value.appendChild(renderer.domElement); //body元素中插入canvas对象
  //执行渲染操作   指定场景、相机作为参数

  let controls = new OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true;
  controls.maxDistance = 9;
  controls.target.set(-0.4, 1, 0);
  controls.maxPolarAngle = Math.PI / 2;
  function loopAnimation() {
    renderer.render(scene, camera);
    // requestAnimationFrame(c)
    controls.update();
  }
};

onBeforeMount(() => {
  threeCar.value = JSON.parse(route.params.threeCar);
  tempImg = threeCar.value[0].vr_list.front_vr;
});
</script>

<style lang="less" scoped>
.three-car {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  .car-header {
    height: 40px;
    width: 100%;
    // margin-bottom: 10px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: linear-gradient(10deg, #eee, #fff, #eee);
    .img {
      width: 15px;
      height: auto;
    }
  }
  .car-content {
    height: 300px;
    width: 100%;
    position: relative;
    #canvas {
      width: 100%;
      height: 300px;
    }
    .car-scale {
      position: absolute;
      z-index: 1001;
      width: 30px;
      height: 30px;
      bottom: 10px;
      right: 10px;
      color: gray;
    }
  }
  .car-color {
    height: 30px;
    width: 100%;
    padding: 0 10px;
    box-sizing: border-box;
    ul {
      height: 40px;
      width: 100%;
      display: flex;
      justify-content: space-evenly;
      align-content: center;
      p {
        line-height: 40px;
        text-align: center;
        height: 24px;
        width: 24px;
        margin: 0;
        margin: 10px 0;
        border-radius: 50px;
      }
    }
  }
  .car-footer {
    flex: 1;
  }
}
</style>